// uni-app 支持跨端的请求库，基于 uni.request 进行封装
import { useUserStore } from '@/stores/user'
import Request, { type HttpMethod, type HttpRequestConfig } from 'luch-request'

// 请求基地址
export const baseURL = 'https://consult-api.itheima.net'

const service = new Request({
	// 请求基地址
	baseURL: baseURL,
	// 超时时间
	timeout: 15 * 1000,
	// 自定义参数
	custom: {
		loading: true
	}
})

// 接口白名单
const whiteList = ['/code', '/login', '/login/password']

// 请求拦截器
service.interceptors.request.use(
	(config) => {
		// 加载提示
		if (config.custom?.loading) {
			// mask: true 显示透明蒙层，防止触摸穿透
			uni.showLoading({ title: '加载中...', mask: true })
		}
		// 添加 token，排除白名单情况
		const store = useUserStore()
		if (store.token && config.url && !whiteList.includes(config.url)) {
			config.header = {
				...config.header,
				Authorization: `Bearer ${store.token}`
			}
		}
		return config
	},
	(error) => {
		return Promise.reject(error)
	}
)

// 响应拦截器
service.interceptors.response.use(
	(res) => {
		uni.hideLoading()
		// 业务状态码，后端约定，code === 10000 为成功
		if (res.data.code !== 10000) {
			uni.showToast({
				title: res.data.message,
				icon: 'none'
			})
			return Promise.reject(res.data)
		}
		// 返回核心数据
		return res.data
	},
	(error) => {
		uni.hideLoading()
		// 401 状态码，后端约定，未登录或登录过期
		if (error.data.code === 401) {
			uni.showToast({
				title: error.data.message,
				icon: 'none'
			})
			// 清除无效的token信息
			const store = useUserStore()
			store.clearToken()
			// 跳转到登录页
			uni.redirectTo({ url: '/pages/login/login' })
		}
		return Promise.reject(error)
	}
)

// 服务端响应数据结构
export interface ServiceResponse<T> {
	code: number
	message: string
	data: T
}

// 封装请求工具
const request = <T>(
	url: string, // 请求地址
	method: HttpMethod = 'GET', // 请求方式
	submitData?: object, // 请求参数
	config?: HttpRequestConfig // 请求配置
) => {
	return service.request<T, ServiceResponse<T>>({
		url: url,
		method: method,
		[method.toUpperCase() === 'GET' ? 'params' : 'data']: submitData,
		...config // 兜底请求配置，可覆盖前面的配置
	})
}

export { service, request }
